package com.chuan.threadpool;

import java.io.Serializable;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Created by zhaowenchuan on 2018/10/31.
 */
public class ThreadPoolExecutorDemo {

    private static int produceTaskSleepTime = 2;
    private static int produceTaskMaxNumber = 10;
    public static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2,
            4,
            3,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<Runnable>(3),
            new ThreadPoolExecutor.CallerRunsPolicy());

    public static void main(String[] args) {

        for (int i = 1; i <= produceTaskMaxNumber; i++) {
            try {
                // 产生一个任务，并将其加入到线程池
                String task = "task@ " + i;
                threadPool.execute(new ThreadPoolTask(task));
                System.out.println("put " + task + "   " + System.currentTimeMillis() + "线程池中线程数目：" + threadPool.getPoolSize() + "，队列中等待执行的任务数目：" +
                        threadPool.getQueue().size() + "，已执行完的任务数目：" + threadPool.getCompletedTaskCount());

                // 便于观察，等待一段时间
                Thread.sleep(produceTaskSleepTime);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        ;
    }
}

class ThreadPoolTask implements Runnable, Serializable {
    private static final long serialVersionUID = 0;
    private static int consumeTaskSleepTime = 2000;
    // 保存任务所需要的数据
    private Object threadPoolTaskData;

    ThreadPoolTask(Object tasks) {
        this.threadPoolTaskData = tasks;
    }

    public void run() {
        // 处理一个任务，这里的处理方式太简单了，仅仅是一个打印语句
        System.out.println(Thread.currentThread().getName() + "     start .." + threadPoolTaskData + "   " + System.currentTimeMillis());
        try {
            // //便于观察，等待一段时间
            Thread.sleep(consumeTaskSleepTime);
        } catch (Exception e) {
            e.printStackTrace();
        }
        threadPoolTaskData = null;
    }

    public Object getTask() {
        return this.threadPoolTaskData;
    }
}